<?php
/**
 * base class for (local) folders
 *
 * This file is part of Webappkit, a packages system for PHP web apps
 * @link http://webappkit.net
 * @package webappkit
 * @subpackage fs
 * @author J.Ducastel <nospam0@ducastel.name>
 * @license http://opensource.org/licenses/gpl-license.php GNU Public License
 */
class WakFolder implements iWakFS, Iterator {

    /**
     * @param string $path
     */
    public function __construct($path) {
        $this->_path=$path;
    }

/*------------------------------------------------------------------------------
WakFS interface methods
------------------------------------------------------------------------------*/

    /**
     * return given path
     * @return string
     */
    public function path() {
        return $this->_path;
    }

    /**
     * @return absolute path, without trailing slashes
     * @return string
     */
    public function realPath() {
        $path=realpath($this->path());
        $last=substr($path,-1,1);
        if ($last=='\\' or $last=='/')
            $path=substr($path,0,-1);
        return $path;
    }

    /**
     * does element exists ?
     * @return bool
     */
    public function exists() {
        return file_exists($this->path());
    }

    /**
    * is the folder readable ?
    * @access public
    * @return bool
    */
    public function isReadable() {
        /*if (PHP_OS=='WINNT')
            return true;*/
        //clearstatcache();
        return is_readable($this->realpath());
    }/**/

    /**
    * is the folder writable ?
    * @return bool
    */
    public function isWritable() {
        /*if (PHP_OS=='WINNT')
            return true;*/
        return is_writable($this->realpath());
    }

    /**
     * get dirname
     * @return string
     */
    public function dirname() {
        return dirname($this->_path);
    }

    /**
     * @return string
     */
    public function basename() {
        return basename($this->_path);
    }

    /**
    * creates dir if not exists
    * @param int $mode
    * @access public
    * @return bool
    */
    public function create($mode=0777) {
        return mkdir($this->_path,$mode);
    }/**/

    /**
    * moves to new path
    * @param string $new_path
    * @access public
    * @return bool
    */
    public function move($new_path) {
        if (!$this->exists())
            return false;
        // normalizing new path
        $new_path=realpath($new_path);
        $last=substr($new_path,-1,1);
        if ($last=='\\' or $last=='/')
            $new_path=substr($new_path,0,-1);

        $old=$this->realPath();
        $new=$new_path.'/'.$this->basename();
        // echo "<p>$old => $new</p>";
        if (!rename($old,$new))
            return false;
        $this->_path=$new;
        return true;
    }

    /**
     * renames folder (new basename within same folder)
     * @return bool
     */
    public function rename($name) {
        $old=$this->realPath();
        $dir=$this->dirname();
        $new=$dir?($dir.'/'.$name):$name; // echo "<p>$old => $new</p>";
        if (!rename($old,$new))
            return false;
        $this->_path=$new;
        return true;
    }

    /**
     * destroy element
     * @return bool
     */
    public function delete() {
        if (!$this->exists())
            return false;
        return rmdir($this->realpath());
    }

/*------------------------------------------------------------------------------
 Iterator interface methods
------------------------------------------------------------------------------*/
    /**
     * return current item in list
     * @return string file name
     * @todo return iWAKFS instance ???
     */
    public function current() {
        $files=$this->_getFiles();
        if (!isset($files[$this->_current]))
            return null;
        return $files[$this->_current];
    }

    /**
     * advance cursor and return new current file
     * @return string
     */
    public function next() {
        $this->_current++;
        return $this->current();
    }

    /**
     * return current key
     * @return int
     */
    public function key() {
        return $this->_current;
    }

    /**
     * reset cursor
     * @return bool
     */
    public function rewind() {
        $this->_current=0;
        return true;
    }

    /**
     * @return bool
     */
    public function valid() {
        $files=$this->_getFiles();
        return isset($files[$this->_current]);
    }

/*------------------------------------------------------------------------------
private part
------------------------------------------------------------------------------*/
    /**
     * return files list. Builds it if necessary
     * @return array
     */
    private function _getFiles() {
        if (!$this->_files) {
            $d=dir($this->realPath());
            while ($file=$d->read()) {
                if ($file!='.' and $file!='..')
                    $this->_files[]=$file;
            }
        }
        return $this->_files;
    }

    /**
     * guesses correct class for a file amongst iWakFS implementations
     * @param string $path filename
     * @return string class
     */
    protected function _guessClass($path) {

    }

    /**
     * @var string self path, as given
     */
    protected $_path;

    /**
     * @var array files list
     */
    protected $_files=array();

    /**
     * @var int files cursor
     */
    protected $_current=0;
}
